#ifndef __SCENARIOS_MANAGER_H__
#define __SCENARIOS_MANAGER_H__
#include <osip2/osip.h>
#include <osip2/osip_dialog.h>
#include <wx/wx.h>
#include <wx/datetime.h>
#include <string>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <wx/filename.h>

WX_DECLARE_STRING_HASH_MAP(wxString, StrStrHash);

class TermControl;
class SttEvt;

class Scenario{
public:
    wxString filename;
    bool EndOnOsipTimeout;
	bool NeedRegiste,AllowAutoAck;
	
    Scenario();
    ~Scenario();
    const wxString &GetIdentifier(){ return Identifier;};
    bool LoadFromFile(wxString fname);
    int GetTermNumNeeded(){return NeedTermNum;};
    bool ReLoad();
    int GetTimeout(){ return timeout; };
    bool IsSourceModified();
    void ExecuteDefaultAction(TermControl& TermIns);
    int ProcessSttEvt(TermControl& TermIns,SttEvt *evt);
    bool TestAndRunRule(TermControl& TermIns,SttEvt *evt,xmlNodePtr RuleNode, bool IsFinalRule=false);
    bool ExecuteSendRule(TermControl& TermIns,SttEvt *evt);
    wxString GetConfigValue(const wxString&key);
    void SetConfigValue(const wxString&key, const wxString&value);
    void InitConfigValue(void);
    wxString GetPatamRealValueAsUnicode(xmlNodePtr Node, const char *v,TermControl& TermIns,Scenario* s=NULL);
    std::string GetPatamRealValue(xmlNodePtr Node, const char *v,TermControl& TermIns,Scenario* s=NULL);
    wxString RealValue(wxString v, TermControl& TermIns, wxString Sep=wxT(" "),xmlNodePtr Node=NULL,Scenario* s=NULL);
    void InitCallVaribles(StrStrHash &Vars);    
    void InitTermVaribles(StrStrHash &Vars, bool ForceInit=false);
    StrStrHash* GetMap(){return &ConfigData;};
    wxString GetConfigGroupPath(void){return wxT("/")+Identifier;};
    int GetNeedTermNum(){return NeedTermNum;};
    static wxString XmlChar2Unicode(xmlChar *v){return wxString(wxConvUTF8.cMB2WC((const char*)v),*wxConvCurrent);};    
    static std::string Conv2Std(const wxString& src);
    void DumpConfig();
    void SetIdentifier(wxString v);
    bool GetRunDefaultRule(){return RunDefaultRule;};
    wxString GetOsipHeadParamValueByName(osip_header_t *ph,const char*paramname);
private:
    StrStrHash ConfigData;
    bool MatchRule(TermControl& TermIns,SttEvt *evt,xmlNodePtr RuleNode);
    bool MatchCondition(TermControl& TermIns,SttEvt *evt,xmlNodePtr CondNode);
    xmlNodePtr GetConditionsNode(xmlNodePtr RuleNode);
    xmlNodePtr GetActionsNode(xmlNodePtr RuleNode);
    bool ExecuteRuleActions(TermControl& TermIns,SttEvt *evt,xmlNodePtr RuleNode);
    bool ExecuteAction(TermControl& TermIns,SttEvt *evt,xmlNodePtr ActionNode);
    xmlXPathObjectPtr GetNodeSet (xmlChar *xpath);
	xmlNode* identnode;
    xmlDocPtr doc;
    int NeedTermNum;
    wxString Identifier;
    wxDateTime  lastmodifytime;
    bool RunDefaultRule;
    int timeout;
    xmlXPathObjectPtr EventRules,TimerRules,RecvRules,VaribleRules,ConfigureRules,SendRules,InitActions,FinalRules;
    xmlXPathContextPtr context;
    void GetRuleNodeSet(void);
};

bool less_ScenarioName(Scenario* m1, Scenario* m2);

WX_DEFINE_ARRAY(Scenario*, ScPtrArray);

class ScenariosManager
{
public:
    Scenario* DefaultScenario;
    ScPtrArray AllScenarios; 
    ScenariosManager();
    ~ScenariosManager();
    void LoadScenariosFrom(const wxString& Dir);
    int GetMaxTermNeeded();
};

typedef bool (*SttActionCallback)(Scenario &Sce, TermControl& TermIns,SttEvt *evt,xmlNodePtr ActionNode);
typedef struct{
    wxString DriverName;
    SttActionCallback Callback;
}SttActionDriver;


typedef bool (*SttConditionCallback)(Scenario &Sce, TermControl& TermIns,SttEvt *evt,xmlNodePtr ActionNode);
typedef struct{
    wxString DriverName;
    SttConditionCallback Callback;
}SttConditionDriver;

int SttActionCmp(const void *p, const void *q);
int SttCondCmp(const void *p, const void *q);
void SttActionDriverInit(void);

#endif
